package com.tanhua.server.service;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VoiceApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Voice;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.VoiceVo;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.Date;

@Service
public class PeachblossomService {
    @Autowired
    private FastFileStorageClient client;

    @Autowired
    private FdfsWebServer webServer;

    @DubboReference
    private VoiceApi voiceApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Value("${tanhua.default.voiceReciveCount}")
    private Integer voiceReciveCount;

    /**
     * 发布音频
     * @param soundFile
     */
    public void saveVoice(MultipartFile soundFile)  throws IOException{
        if(soundFile.isEmpty()) {
            throw new BusinessException(ErrorResult.error());
        }
        //1、将音频上传到FastDFS,获取访问URL
        String filename = soundFile.getOriginalFilename();  // abc.mp4
        filename = filename.substring(filename.lastIndexOf(".")+1);
        StorePath storePath = client.uploadFile(soundFile.getInputStream(), soundFile.getSize(), filename, null);
        String voiceUrl = webServer.getWebServerUrl() + storePath.getFullPath();
        //2、构建voice对象
        Voice voice = new Voice();
        voice.setUserId(UserHolder.getUserId());
        voice.setVoiceUrl(voiceUrl);
        //3、调用API保存数据
        String voiceId = voiceApi.save(voice);
        if(StringUtils.isEmpty(voiceId)) {
            throw new BusinessException(ErrorResult.error());
        }
    }

    /**
     * 接收音频
     */
    public VoiceVo reciveVoice() {
        //1、获取语音获取剩余次数(构造当前用户在当天的rediskey)
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String nowDay = format.format(new Date());
        String key = Constants.VOICE_COUNT + nowDay + "_" + UserHolder.getUserId().toString();
        boolean hasKey = redisTemplate.hasKey(key);
        VoiceVo voiceVo;
        //2、判断key是否存在
        if(!hasKey){
            //当天第一次获取音频
            voiceVo = this.getVoiceVo();
            redisTemplate.opsForValue().set(key, (--voiceReciveCount).toString(), Duration.ofSeconds(this.getSencond()));
            voiceVo.setRemainingTimes(voiceReciveCount);
        }else{
            Long count = Long.valueOf(redisTemplate.opsForValue().get(key));
            if(count <= 0){
                throw new BusinessException(ErrorResult.voiceEmptyError());
            }
            voiceVo = this.getVoiceVo();
            count = redisTemplate.opsForValue().decrement(key);
            voiceVo.setRemainingTimes(count.intValue());
        }
        return voiceVo;
    }

    private long getSencond() {
        String str = DateUtil.tomorrow().toDateStr() + " 00:00:00";
        long between = DateUtil.between(new Date(),DateUtil.parse(str) , DateUnit.SECOND);
        return between;
    }

    private VoiceVo getVoiceVo() {
        Voice voice = this.voiceApi.randomVoice();
        if (voice == null) {
            throw new BusinessException(ErrorResult.noVoiceError());
        }
        UserInfo userInfo = userInfoApi.findById(voice.getUserId());
        this.voiceApi.updateState(voice.getId().toString(), true);
        return VoiceVo.init(userInfo,voice);
    }
}
